/********************************************************************

Write Date: 2015/04/21
Author: Apple
>>>> Create class ThisPtr

Modify Date: 2015/04/26
Author: Apple
>>>> Add const to the paremeter of copy constructor and copy assignment.

*********************************************************************/
#pragma once
#include "Ptr.h"



/**
 * Macro THISOBJ provides an alias to create a ThisPtr from 'this'
 */
#ifndef THISOBJ
#define THISOBJ (OOP::createThisPtr (this))
#endif



_NS_OOP_BEGIN



/**
 * Class ThisPtr is used to reference an Object in its function. Normally you 
 * can use tranditional 'this' pointer, but in some cases where you need to 
 * convert 'this' to a Ptr and pass it to a function outside, you should to
 * use ThisPtr to wrap 'this'. Creating or destroying a ThisPtr will not cause
 * the Object's reference count change because it is referenced inside itself.
 *
 * DO NOT create a ThisPtr to an Object outside its functions.
 *
 * Thread-Safe: yes
 *
 * @remarks 2015/04/21, Apple
 */
template< class T >
class ThisPtr : public Ptr< T >
{
public:

	/**
	 * Create a ThisPtr pointing to an Object
	 *
	 * @param p_obj - the Object to point to
	 */
	ThisPtr (T* p_obj);

	/**
	 * Create a ThisPtr and move another's data to it
	 *
	 * @param right - the ThisPtr to move from
	 */
	ThisPtr (ThisPtr< T >&& right);

	/**
	 * Destroy a ThisPtr
	 */
	virtual ~ThisPtr ();

	/* Functions below are forbidden */
	ThisPtr (const ThisPtr< T >& right) = delete;
	ThisPtr< T >& operator= (const ThisPtr< T >& right) = delete;
	ThisPtr< T >& operator= (ThisPtr< T >&& right) = delete;

};



/**
 * Create a ThisPtr pointing to an Object. This template function utilizes the 
 * compiler's type inference so you needn't to type the Type when creating a 
 * ThisPtr.
 *
 * @param p_obj - the Object to point to
 * @return the ThisPtr created
 */
template< class T >
ThisPtr< T > createThisPtr (T* p_obj);



_NS_OOP_END



#include "ThisPtr.hpp"